package com.yunqi.usbprinter;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.util.Log;
import com.printsdk.cmd.PrintCmd;

public class USBPrinterMgr {
    private static final String TAG = "USBPrinterMgr";
    private final static int PID11 = 8211;
    private final static int PID13 = 8213;
    private final static int PID15 = 8215;
    private final static int VENDORID = 1305;
    private static USBPrinterMgr mUSBPrinterMgr;
    private Context mContect;
    private UsbManager mUsbManager;
    private MyUsbDriver mUsbDriver;
    private UsbDevice mUsbDev1;        //打印机1
    private UsbDevice mUsbDev2;        //打印机2
    private BroadcastReceiver mUsbReceiver;
    public static USBPrinterMgr getInstance() {
        if (mUSBPrinterMgr == null)
            mUSBPrinterMgr = new USBPrinterMgr();
        return mUSBPrinterMgr;
    }


    public void init(Context context) {
        mContect=context;
        mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        mUsbDriver = new MyUsbDriver(mUsbManager, context);
        mUsbReceiver = new USBPrinterBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        context.registerReceiver(mUsbReceiver, filter);
    }

    public void destory(){
        if(mUsbReceiver!=null)
            mContect.unregisterReceiver(mUsbReceiver);
        closedPrinter();
    }

    public boolean isConnected() {
        boolean blnRtn = false;
        try {
            if (!mUsbDriver.isConnected()) {
                // USB线已经连接
                for (UsbDevice device : mUsbManager.getDeviceList().values()) {
                    if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
                            || (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
                            || (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
                        if (!mUsbManager.hasPermission(device)) {
                            Log.e(TAG, " mUsbManager has not permission!");
                            break;
                        }
                        blnRtn = mUsbDriver.usbAttached(device);
                        if (blnRtn == false) {
                            Log.e(TAG, " mUsbManager has not attached!");
                            break;
                        }
                        blnRtn = mUsbDriver.openUsbDevice(device);
                        // 打开设备
                        if (blnRtn) {
                            if (device.getProductId() == PID11) {
                                mUsbDev1 = device;
                            } else {
                                mUsbDev2 = device;
                            }
                            setClean();// 清理缓存，初始化
                            Log.i(TAG, " USB Driver connection Success!");
                            break;
                        } else {
                            Log.e(TAG, " USB Driver connection Failed!");
                            break;
                        }
                    }
                }
            } else {
                blnRtn = true;
                Log.e(TAG, " USB Driver has connected!");
            }
        } catch (Exception e) {
            Log.e(TAG, " USB Driver Exception!");
        }
        return blnRtn;
    }

    // 检测打印机状态
    private int getPrinterStatus(UsbDevice usbDev) {
        int iRet = -1;
        byte[] bRead1 = new byte[1];
        byte[] bWrite1 = PrintCmd.GetStatus1();
        if (mUsbDriver.read(bRead1, bWrite1, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus1(bRead1[0]);
        }
        if (iRet != 0)
            return iRet;
        byte[] bRead2 = new byte[1];
        byte[] bWrite2 = PrintCmd.GetStatus2();
        if (mUsbDriver.read(bRead2, bWrite2, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus2(bRead2[0]);
        }
        if (iRet != 0)
            return iRet;
        byte[] bRead3 = new byte[1];
        byte[] bWrite3 = PrintCmd.GetStatus3();
        if (mUsbDriver.read(bRead3, bWrite3, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus3(bRead3[0]);
        }
        if (iRet != 0)
            return iRet;
        byte[] bRead4 = new byte[1];
        byte[] bWrite4 = PrintCmd.GetStatus4();
        if (mUsbDriver.read(bRead4, bWrite4, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus4(bRead4[0]);
        }
        return iRet;
    }

    private int checkStatus(int iStatus) {
        int iRet = -1;
        StringBuilder sMsg = new StringBuilder();
        //0 打印机正常 、1 打印机未连接或未上电、2 打印机和调用库不匹配
        //3 打印头打开 、4 切刀未复位 、5 打印头过热 、6 黑标错误 、7 纸尽 、8 纸将尽
        switch (iStatus) {
            case 0:
                sMsg.append(Constant.Normal_CN);       // 正常
                iRet = 0;
                break;
            case 8:
                sMsg.append(Constant.PaperWillExhausted_CN); // 纸将尽
                iRet = 0;
                break;
            case 3:
                sMsg.append(Constant.PrintHeadOpen_CN); //打印头打开
                break;
            case 4:
                sMsg.append(Constant.CutterNotReset_CN);
                break;
            case 5:
                sMsg.append(Constant.PrintHeadOverheated_CN);
                break;
            case 6:
                sMsg.append(Constant.BlackMarkError_CN);
                break;
            case 7:
                sMsg.append(Constant.PaperExhausted_CN);     // 纸尽==缺纸
                break;
            case 1:
                sMsg.append(Constant.NoConnectedOrNoOnPower_CN);
                break;
            default:
                sMsg.append(Constant.Abnormal_CN);     // 异常
                break;
        }
        return iRet;
    }

    private void closedPrinter(){
        if (!isConnected()) {
            Log.w(TAG, "USB Driver connection Failed!");
            return;
        }
        if (mUsbDev1 != null) {
            mUsbDriver.closeUsbDevice(mUsbDev1);
        }else if (mUsbDev2 != null) {
            mUsbDriver.closeUsbDevice(mUsbDev2);
        }
        else {
            Log.e(TAG, "NO USB Driver connected!");
        }
    }


    public void startPrint(String printStr) {
        if (!isConnected()) {
            Log.w(TAG, "USB Driver connection Failed!");
            return;
        }
        if (mUsbDev1 != null) {
            printTicker(mUsbDev1,printStr);
        }else if (mUsbDev2 != null) {
            printTicker(mUsbDev2,printStr);
        }
        else {
            Log.e(TAG, "NO USB Driver connected!");
        }
    }

    /**
     * 2.小票打印
     */
    public void printTicker(UsbDevice usbDev,String printStr) {
        int iStatus = getPrinterStatus(usbDev);
        Log.e(TAG, " iStatus="+iStatus);
        if (checkStatus(iStatus) != 0) {
            Log.e(TAG, " checkStatus(iStatus) != 0");
            return;
        }
        try {
            // 小票标题
            Log.e(TAG, " -------------start print-------------");
            mUsbDriver.write(PrintCmd.SetBold(0), usbDev);
            mUsbDriver.write(PrintCmd.SetAlignment(1), usbDev);
            mUsbDriver.write(PrintCmd.SetSizetext(1, 1), usbDev);
            mUsbDriver.write(PrintCmd.PrintString(Constant.TITLE_CN, 0), usbDev);
            //欢迎
            mUsbDriver.write(PrintCmd.SetSizetext(0, 0), usbDev);
            mUsbDriver.write(PrintCmd.PrintString(Constant.WELCOME_CN, 0), usbDev);
            // 小票主要内容
            mUsbDriver.write(PrintCmd.SetAlignment(0), usbDev);
            mUsbDriver.write(PrintCmd.PrintString(printStr, 0), usbDev);
            mUsbDriver.write(PrintCmd.PrintFeedline(2), usbDev); // 打印走纸2行
            // 走纸换行、切纸、清理缓存
            setFeedCut(0, usbDev);
            Log.e(TAG, " -------------end print-------------");

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    // 走纸换行、切纸、清理缓存
    private void setFeedCut(int iMode, UsbDevice usbDev) {
        mUsbDriver.write(PrintCmd.PrintFeedline(5), usbDev);      // 走纸换行
        mUsbDriver.write(PrintCmd.PrintCutpaper(iMode), usbDev);  // 切纸类型
    }

    // 走纸换行、切纸、清理缓存
    private void setFeedCut(int iMode) {
        mUsbDriver.write(PrintCmd.PrintFeedline(5));      // 走纸换行
        mUsbDriver.write(PrintCmd.PrintCutpaper(iMode));  // 切纸类型
    }

    // 常规设置
    private void setClean() {
        mUsbDriver.write(PrintCmd.SetClean());// 清除缓存,初始化
    }

    class USBPrinterBroadcastReceiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                if (mUsbDriver.usbAttached(intent)) {
                    UsbDevice device = (UsbDevice) intent
                            .getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
                            || (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
                            || (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
                        if (mUsbDriver.openUsbDevice(device)) {
                            if (device.getProductId() == PID11)
                                mUsbDev1 = device;
                            else
                                mUsbDev2 = device;
                        }
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                UsbDevice device = (UsbDevice) intent
                        .getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
                        || (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
                        || (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
                    mUsbDriver.closeUsbDevice(device);
                    if (device.getProductId() == PID11)
                        mUsbDev1 = null;
                    else
                        mUsbDev2 = null;
                }
            }
        }
    }

    ;
}
